#include "Emitter.h"
#include "../IGraphics.h"
#include "../Resources.h"
#include <random>

Emitter::Emitter(void)
{
	m_bAlive = false;
}

Emitter::~Emitter(void)
{
}

// Circularly allocate an amount of particle types passed in
void Emitter::AllocateParticles(unsigned int typeIndex, int num)
{
	for(int i = 0; i < num; i++)
	{
		m_Particles[m_nCurActive].InitParticle(this, typeIndex, m_nCurActive++);
		if( m_nCurActive > MAX_PARTICLES )
			m_nCurActive = 0;
	}
}

// Initialize particle data with .xml file sent in
void Emitter::Init(const char* ParticleFile)
{
	m_bAlive = true;
	m_Types[0].m_hTexture = IGraphics::GetInstance()->LoadTexture("resources/graphics/fireparticle.dds");
	m_Types[0].m_nNumSpawn = 3;
	m_Types[0].m_fAccel = 15.0f;
	m_Types[0].m_fDirVec.x = 1.0f;
	m_Types[0].m_fDirVec.y = 1.0f;
	m_Types[0].m_fRemainingLifetime = 1.5f;
	m_Types[0].m_fStartPos.x = 50.0f;
	m_Types[0].m_fStartPos.y = 50.0f;

	m_nTotalActive = 0;
	m_nCurActive = 0;
	m_nTotalActiveTypes = 1;
}

// update currently active particles
// also activate new particles every frame
void Emitter::Update(float fElapsedTime)
{
	unsigned int rndType = rand() % m_nTotalActiveTypes;
	if(m_Types[rndType].m_nNumSpawn + m_nTotalActive < MAX_PARTICLES)
	{
		m_nTotalActive += rand() % m_Types[rndType].m_nNumSpawn;
		AllocateParticles(rndType, m_Types[rndType].m_nNumSpawn);
	}

	for(int i = 0; i < MAX_PARTICLES; i++)
	{
		if( m_Particles[i].m_fRemainingLifetime >= 0 )
		{
			m_Particles[i].m_fPos.x += m_Particles[i].m_fDir.x * m_Particles[i].m_fAccel * fElapsedTime;
			m_Particles[i].m_fPos.y += m_Particles[i].m_fDir.y * m_Particles[i].m_fAccel * fElapsedTime;
			m_Particles[i].m_fRemainingLifetime -= fElapsedTime;
		}
	}
}

// render currently active particles
void Emitter::Render(void)
{
	IGraphics* gfx = IGraphics::GetInstance();
	//gfx->BeginScene();
	for(int i = 0; i < MAX_PARTICLES; i++)
	{
		if( m_Particles[i].m_fRemainingLifetime >= 0 )
			gfx->DrawTexture(m_Particles[i].m_hTexture, m_Particles[i].m_fPos.x, m_Particles[i].m_fPos.y, 0.0f, 0.0f, 0.0f, SColor(255, 0, 0, 100));
	}
	//gfx->EndScene();
}

// end the rest of the particles lives
// also reinitialize the new emitter if nextParticle isn't null
void Emitter::Destroy(void)
{
	for(int i = 0; i < MAX_TYPES; i++)
	{
		if( m_Types[i].m_hTexture != INVALID_HANDLE )
			IGraphics::GetInstance()->UnloadTexture(m_Types[i].m_hTexture);
	}

	for(int i = 0; i < MAX_PARTICLES; i++)
		m_Particles[i].m_fRemainingLifetime = -1.0f;
}

void Emitter::Particle::InitParticle(Emitter* mEmit, unsigned int nType, int nIndex)
{
	mEmit->m_Particles[nIndex].m_fPos = mEmit->m_Types[nType].m_fStartPos;
	mEmit->m_Particles[nIndex].m_hTexture = mEmit->m_Types[nType].m_hTexture;
	mEmit->m_Particles[nIndex].m_fAccel = mEmit->m_Types[nType].m_fAccel;
	mEmit->m_Particles[nIndex].m_fDir.x = rand() % 15 * mEmit->m_Types[nType].m_fDirVec.x;
	mEmit->m_Particles[nIndex].m_fDir.y = rand() % 15 * mEmit->m_Types[nType].m_fDirVec.y;
	mEmit->m_Particles[nIndex].m_fRemainingLifetime = mEmit->m_Types[nType].m_fRemainingLifetime;
}